home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / Libraries / SAT 2.3b4 / Demo ƒ / SAT Invaders demo ƒ / main.c < prev    next >
Text File  |  1995-04-30  |  9KB  |  352 lines

  1. //• C translation from Pascal source file: main.p
  2.  
  3. //• ================================================.
  4. //• =============== SATInvaders main unit ================.
  5. //• ================================================.
  6.  
  7. //• Example file for Ingemars Sprite Animation Toolkit.
  8. //• © Ingemar Ragnemalm 1992.
  9. //• See doc files for legal terms for using this code.
  10.  
  11. //• SATInvaders is a very simple game demonstrating how to use the Sprite Animation.
  12. //• Toolkit. It is intended as a minimal demonstration, without many features and options.
  13. //• that the other sample program, HeartQuest, has. No high scores or even score, only.
  14. //• one life, doesn't save settings, only one kind of enemy, no special effects like explosions.
  15. //• etc.
  16.  
  17. //• main SATInvaders.c
  18.  
  19. #include <TransSkel.h>
  20. #include <SAT.h>
  21. #include "InvadeSAT.h"
  22. //#include "GameGlobals.h"
  23. //• SoundConst, sPlayer, sEnemy, sShot, sMissile;
  24.  
  25. // All the following is now in InvadeSAT.h
  26. //extern void        InitEnemy(void);
  27. //extern pascal void        SetupEnemy(SpritePtr sp);
  28. //extern pascal void        HandleEnemy(SpritePtr me);
  29. //extern void        InitPlayer(void);
  30. //extern pascal void        SetupPlayer(SpritePtr player);
  31. //extern pascal void        HandlePlayer(SpritePtr me);
  32.  
  33. Boolean soundFlag, plotFastFlag;
  34.  
  35. //• --------------------------------------------------------------------.
  36. //•                     Game driver procedures                                .
  37. //• --------------------------------------------------------------------.
  38.  
  39. //• Setup a new level. This is called when the game starts and at each new level.
  40. void SetUpLevel (short level)
  41. {
  42.     short i, j;
  43.     SpritePtr sp;
  44.     
  45.     //• Clear the Sprite list.
  46.     while (gSAT.sRoot) SATKillSprite(gSAT.sRoot);
  47.     
  48.     missileCount = 0;     //• global count variable
  49.  
  50.     //• Create all the enemy sprites for the level, depending on the level number.
  51.     for (i = 0; i <= (level + 1); i++)
  52.         for (j = 0; j <= (level / 2) + 1; j++)
  53.             sp = SATNewSprite (-3, i * 40 + 2, j * 40 - 40 * (level / 2 + 1), &SetupEnemy);
  54.  
  55.     //• Make the player sprite.
  56.     sp = SATNewSprite (2, gSAT.offSizeH / 2, gSAT.offSizeV - 40, &SetupPlayer);
  57.  
  58.     //• Copy backScreen to offScreen to erase old sprites.
  59.     CopyBits (&(gSAT.backScreen.port->portBits), &(gSAT.offScreen.port->portBits), &(gSAT.offScreen.port->portRect), &(gSAT.offScreen.port->portRect), srcCopy, 0L);
  60.     SATRedraw ();
  61. }     //• SetUp Level.
  62.  
  63. //• Start a new game. Initialize level, score, number of lives, and call SetUp Level to make the first level.
  64. void StartGame ()
  65. {
  66.     level = 1;
  67.     SetUpLevel (level);
  68. }
  69.  
  70. void DoFileMenu (short item)
  71. {
  72.     switch (item)
  73.     {
  74.         case run: 
  75.         {
  76.         //• Test if we have Color QD, and if so, test bit depth! Alert if ((**features).PlotFast)
  77.             if (!((gSAT.initDepth == 1) || 
  78.                   (gSAT.initDepth == 4) || 
  79.                   (gSAT.initDepth == 8)) && plotFastFlag)
  80.             {
  81.                 SATReportStr ("\pPlease uncheck 'Fast animation' or set the monitor to b/w, 4-bit or 8-bit mode in the Control Panel.");
  82.                 return;
  83.             }
  84.             if (SATDepthChangeTest())     //• Update if necessary.
  85.                 ;
  86.             StartGame ();
  87.             ShowWindow (gSAT.wind.port);
  88.             SelectWindow (gSAT.wind.port);
  89.             GameWindUpdate (false, 0);
  90.             MoveIt ();
  91.         }
  92.         break;
  93.         
  94.         case sound: 
  95.         {
  96.             soundFlag = ! soundFlag;
  97.             CheckItem (fileMenu, sound, soundFlag);
  98.             if (soundFlag)     //• Tell the sound package our settings, so we don't have to bother.
  99.                 SATSoundOn();
  100.             else
  101.                 SATSoundOff();
  102.         }
  103.         break;
  104.  
  105.         case fastAnimation: 
  106.         {
  107.             plotFastFlag = ! plotFastFlag;
  108.             CheckItem (fileMenu, fastAnimation, plotFastFlag);
  109.         }
  110.         break;
  111.         
  112.         case quit: 
  113.             SkelWhoa ();
  114.         break;
  115.     }
  116. }
  117.  
  118. void MoveIt (void)
  119. {
  120.     long t;
  121.     EventRecord theEvent;     //• för att testa musklick.
  122.  
  123.     stillRunning = true;     
  124.  
  125.     //• Hide cursor and menu bar
  126.     //• NOTE: No matter how we leave the MoveIt procedure, we should 
  127.     //• ShowCursor and ShowMBar!
  128.     HideCursor ();
  129.     SATHideMBar(gSAT.wind.port);
  130.     SATRedraw();    //• We must redraw the menu bar area. I'm lazy and redraw it all.
  131.  
  132.     //• Main loop! Keep running until the game is paused or ends.
  133.     while (stillRunning == true)
  134.     {
  135.         t = TickCount ();
  136.  
  137.         //• Here is the real heart of the loop: call Animator once per loop. 
  138.         //• It will call all the objects.
  139.         SATRun (plotFastFlag);
  140.  
  141.         //• All the rest of the main loop is game specific, next level, 
  142.         //• bonus handling, etc.
  143.         if (globalSpeed.h == 0)
  144.         {
  145.             downCount--;
  146.             if (downCount <= 0)
  147.             {
  148.                 globalSpeed.h = - last_H;
  149.                 globalSpeed.v = 0;
  150.                 turnFlag = false;
  151.             };
  152.         }
  153.         else 
  154.             if (turnFlag)
  155.             {
  156.                 downCount = 10;
  157.                 last_H = globalSpeed.h;
  158.                 globalSpeed.h = 0;
  159.                 globalSpeed.v = 3;
  160.             };
  161.         if (! gSAT.anyMonsters)
  162.         {
  163.             SATSoundShutup  ();
  164.             level++;
  165.             SetUpLevel (level);
  166.         }     //• if not anyMonsters.
  167.  
  168.         //• Check for keys being pressed - but don't allow background 
  169.         //• processing.
  170.         //• If you want background processing, either use 
  171.         //• GetNextEvent+SystemTask or WaitNextEvent (the modern call).
  172.         if (GetOSEvent (keyDownMask, &theEvent))     //• keydown.
  173.             if ((theEvent.modifiers & cmdKey) != 0)
  174.                 switch ((theEvent.message & charCodeMask))
  175.                 {
  176.                     case 'q': 
  177.                     {
  178.                         SkelWhoa ();
  179.                         //• Do all the things we have to do when we 
  180.                         //• leave MoveIt!.
  181.                         SATSoundShutup ();     //• Dispose of sound channel.
  182.                         FlushEvents (everyEvent, 0);     //• To forget events, like mouse clicks etc.
  183.                         ShowCursor ();
  184.                         SATShowMBar(nil);
  185.                         return;
  186.                     }
  187.                     break;
  188.                     case 's': 
  189.                     {
  190.                         DoFileMenu (sound);
  191.                     }
  192.                     break;
  193.                     
  194.                     default:
  195.                     break;
  196.                 };     //• switch.
  197.         
  198.         //• Delay, using TickCount so it doesn't matter how fast 
  199.         //• our Mac is.
  200.         while ((TickCount () - t) < 3);
  201.  
  202.     } //while stillRunning; (main loop).
  203.  
  204.     while (! SATSoundDone() )
  205.         SATSoundEvents ();     //• Wait for last sound to complete.
  206.  
  207.     ShowCursor ();
  208.     SATShowMBar(nil);
  209.     FlushEvents (everyEvent, 0);     //• To forget Events, like mouse clicks etc.
  210.  
  211.     SATReportStr ("\pSorry, game over.");
  212.  
  213.     SATSoundShutup ();     //• Dispose of sound channel.
  214. }     //• MoveIt.
  215.  
  216. void GameWindUpdate (Boolean resized, short mods)
  217. {
  218.     CursHandle watch;
  219.  
  220.     watch = GetCursor (watchCursor); /* WatchCursor */
  221.     SetCursor (*watch);
  222.     if (SATDepthChangeTest() )
  223.     {
  224.         ;
  225.     }
  226.     InitCursor ();
  227.     ReleaseResource ((Handle) watch);
  228.  
  229.     SATRedraw ();
  230. } //GameWindUpdate
  231.  
  232. //• Process selection from File menu.
  233.  
  234. void GameWindIdle ()
  235. {
  236. }
  237.  
  238. void GameWindInit (void)
  239. {
  240.     Boolean dummy;
  241.     
  242.     //• Tell TransSkel to tell us when to update gSAT.wind.
  243.     dummy = SkelWindow (gSAT.wind.port, 0L, 0L, &GameWindUpdate, 0L, 0L, 0L, &GameWindIdle, false);
  244.  
  245.     //• Set up the two offScreen GrafPorts "offScreen" and "backScreen". SAT has a standard.
  246.     //• way to do this. Let SAT draw the background PICT for us, too.
  247.  
  248.     //• Call the Init routines for all the sprite units!.
  249.     InitEnemy ();
  250.     InitPlayer ();
  251.     InitMissile ();
  252.     InitShot ();
  253.  
  254.     // We must show the window ourselves when using SATCustomInit
  255.     ShowWindow (gSAT.wind.port);
  256.     SelectWindow (gSAT.wind.port);
  257.     //• Draw the contents of the window (to give the user something to 
  258.     //• look at during the rest of startup).
  259.     SATRedraw ();
  260. }
  261.  
  262. //• --------------------------------------------------------------------.
  263. //•             Menu handling procedures                        .
  264. //• --------------------------------------------------------------------.
  265.  
  266. //• Handle selection of "About…" item from Apple menu.
  267.  
  268. void DoAbout (void)
  269. {
  270.     short ignore;
  271.     Str255 versionString;
  272.  
  273.     SATGetVersion(versionString);
  274.     ParamText(versionString, "\p", "\p", "\p");
  275.     ignore = Alert (aboutAlrt, 0L);
  276. }
  277.  
  278. //• Initialize menus.  Tell TransSkel to process the Apple menu.
  279. //• automatically, and associate the proper procedures with the.
  280. //• File menu.
  281.  
  282. void SetUpMenus ()
  283. {
  284.     SkelApple ("\pAbout SAT Invaders…", &DoAbout);
  285.     fileMenu = GetMenu (fileMenuRes);
  286.     SkelMenu (fileMenu, &DoFileMenu, 0L, false, true);
  287.     //• Set the following flags so they match the menu.
  288.     soundFlag = true;
  289.     plotFastFlag = true;
  290. }
  291.  
  292. //• Hide gamewindow on suspend, so the user can get access to disk icons etc.
  293.  
  294. void DoSuspendResume (Boolean b)
  295. {
  296.     if (b)
  297.     {
  298.         ShowWindow (gSAT.wind.port);
  299.         SelectWindow (gSAT.wind.port);
  300.     }
  301.     else
  302.         HideWindow (gSAT.wind.port);
  303. }
  304.  
  305. Boolean DoEvt (EventRecord *e)
  306. {
  307.     if (e->what == osEvt)
  308.     {
  309.         if (((e->message, 8), 0xFF) == suspendResumeMessage)
  310.             DoSuspendResume ((e->message, 1) != 0);
  311.         return true;
  312.     }
  313.     else
  314.         return false;
  315. }     //• end DoEvent *.
  316.  
  317. //• --------------------------------------------------------------------.
  318. //•                             Main                                .
  319. //• --------------------------------------------------------------------.
  320. void main (void)
  321. {
  322.     Rect    gameArea;
  323.     
  324.     SkelInit (nil, 6);                //• Initialize.
  325.  
  326.     //• Init all the different parts of the game.
  327.     SetUpMenus ();        //• install menu handlers.
  328.     
  329.     SetRect(&gameArea, 0, 0, 512, 342);
  330.  
  331.     //• We use SATCustomInit to cover the full screen INCLUDING menu bar area!
  332.     SATCustomInit(129, 128, &gameArea, nil, nil, true, true, true, true, true);
  333. //SATInit (129, 128, 512, 322);
  334.  
  335.     GameWindInit ();    //• Init the game window.
  336.     LoadSounds ();        //• preload all sound resources.
  337.  
  338.     //• Set the randseed to something that is random enough.
  339. #ifdef THINKC
  340.     randSeed = TickCount ();
  341. #else
  342.     qd.randSeed = TickCount ();
  343. #endif
  344.  
  345.     SkelEventHook (&DoEvt); //• handle MultiFinder-Events.
  346.  
  347.     SkelMain ();                //• loop 'til Quit selected.
  348.     SkelClobber ();                //• clean up.
  349.     SATSoundShutup ();            //• Terminate sounds.
  350. }
  351.  
  352.